package Java8;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author VX5
 * @Title: MJC
 * @ProjectName DataStructure
 * @Description: TODO
 * @date ${DAT}10:31
 *
 * 一、Stream 的三个操作步骤
 *
 * 1、创建Stream
 * 2、中间操作
 * 3、终止操作 终端操作
 */
public class TestStreamAPI1 {

    //创建Stream
    @Test
    public void test1(){
        //1、可以通过Collection 系列集合提供的stream()或者parallelStream（）并行流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();//得到流

        //2、通过Arrays中的静态方法stream()获取数组流
        Apple[] apples = new Apple[10];
        Stream<Apple> stream2 = Arrays.stream(apples);

        //3、通过Stream类中的静态方法of（）
        Stream<String> stream3 = Stream.of("aa","bb","cc");

        //4、创建无限流
        //迭代
        Stream<Integer> stream4 = Stream.iterate(0,(x) -> x + 2);

        stream4.limit(10).forEach(System.out::println);
    }

    //中间操作

    /**
     * 筛选与切片
     * filter-接受Lambda,从流中排除某些元素
     * limit-截断流，使其元素不超过给定数量
     * skip(n)-跳过元素，返回一个扔掉了前n个元素的流。若流中元素不是n个，则返回一个空流。与limit(n)互补
     * distinct-筛选,通过流所生成元素的hashCode（）和equals()去除重复元素
     */
    @Test
    public void test2(){
        List<Apple> apples = Arrays.asList(
                new Apple("red",100),
                new Apple("blue",100),
                new Apple("yellow",200)
        );



        //中间操作
        Stream<Apple> stream = apples.stream()
                .filter((e) -> {
                    System.out.println("中间操作");
                    return e.getWeight() >= 100;
                })
                .limit(3)
                .skip(2);//加了限制就像短路，之后的迭代就不用进行了

        //终止操作，一次性执行全部内容，（惰性求值）
        stream.forEach(System.out::println);

//        List<Apple> list = stream.collect(Collectors.toList());
//        System.out.println(list.size());
    }

    //映射
    //map接受Lambda,将元素转换成其他心事或提取信息，接受一个函数作为参数，该函数会被运用到每个元素上，并将映射成一个新的元素。
    //flatMap接收一个函数作为参数，将六中的每个值都换成另一个流，然后把所有流连接成一个流
    @Test
    public void test3(){
        List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
        list.stream().map((str)->str.toUpperCase()).forEach(System.out::println);


    }

    //排序
    /*
    sorted()——自然排序(Comparable)->CompareTo
    sorted(Comparator com)-定制排序)(Comparator)
     */
    @Test
    public void test4(){
        List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");

        list.stream().sorted().forEach(System.out::println);
        List<Apple> apples = Arrays.asList(
                new Apple("red",300),
                new Apple("blue",100),
                new Apple("yellow",200)
        );

        apples.stream()
                .sorted((a1,a2)->{
                    if (a1.getWeight()==a2.getWeight()){
                        return a1.getColor().compareTo(a2.getColor());
                    }else {
                        return Long.compare(a1.getWeight(),a2.getWeight());
                    }
                }).forEach(System.out::println);
    }


    //终止操作
    /*
    allMatch-检查是否匹配所有元素
    anyMatch-检查是否至少匹配一个元素
    noneMatch-检查是否没有匹配所有元素
    findFirst-返回第一个元素
    findAny-返回当前流中的任意元素
    count-返回六中元素的个数
    max-返回流中最大值
    min-返回流中最小值
     */
    @Test
    public void test5(){
        List<Apple> apples = Arrays.asList(
                new Apple("red",100),
                new Apple("blue",100),
                new Apple("yellow",100)
        );
        boolean b1 = apples.stream().allMatch((a) -> a.getWeight() == 100);
        System.out.println(b1);
    }

    /*
    归约
    reduce(T identity,BinaryOperator) / reduce(BinaryPoerator) -- 可以将流中元素反复结合起来，得到一个值
     */
}
